package sky.treasure;

import sky.treasure.results.*;

import java.util.Stack;

/**
 * Created with IntelliJ IDEA.
 * User: Gauss
 * Date: 08.01.14
 * Time: 0:35
 * To change this template use File | Settings | File Templates.
 */
public class TypicalTreasureHunter implements ITreasureHunter {

    private Stack<ICoordinator> coordinators;
    private ICoordinator coordinator;
    private Coordinates coordinates;

    public TypicalTreasureHunter(ICoordinator coordinator) {
        this.coordinator = coordinator;
        coordinators = new Stack<ICoordinator>();
        coordinators.push(coordinator);
    }

    public void addCoordinator(ICoordinator coordinator) {
        coordinators.push(coordinator);
        this.coordinator = coordinator;
    }

    public IResult findTreasure() {
        Cell cell = coordinator.getFirstCell();
        coordinates = cell.getCoordinates();
        IResult result = interactWithCell(cell);
        while (!coordinators.empty()) {
            coordinator = coordinators.pop();
            if (result.getClass().equals(EndOfAlgorithm.class)) {
                result = new Result();
            }
            while (!isEnd(result)) {
                cell = coordinator.getNextCell(coordinates);
                result = analyzeCell(cell);
                if (result.getClass()==Result.class) {
                    move(cell);
                }
                result = result.make(this, cell);
                if (result!=null && result.getClass()!=EndOfAlgorithm.class) {
                    result = interactWithCell(cell);
                }
            }
        }
        return result;
    }

    public IResult analyzeCell(Cell cell) {
        if (cell.getProperties() == null || cell.getProperties().size()==0) return new Result();
        return cell.getProperties().get(0).analyzeCell(cell);
    }

    @Override
    public void move(Cell cell) {
        this.coordinates = cell.getCoordinates();
    }

    private IResult interactWithCell(Cell cell) {
        if (cell.getProperties() == null || cell.getProperties().size()==0) return new Result();
        return cell.getProperties().get(0).interactWithCell(cell);
    }

    private boolean isEnd(IResult result) {
        return (result.getClass() == EndOfAlgorithm.class||result.getClass() == DeathFound.class||result.getClass() == TreasureFound.class);
    }

    @Override
    public Coordinates getCoordinates() {
        return coordinates;
    }

    @Override
    public ICoordinator getCoordinator() {
        return coordinator;
    }

    public void setCoordinator(ICoordinator coordinator) {
        this.coordinator = coordinator;
    }
}
